const Net = require('net')
const Response = require("./Response")
const RunTime = require("./Config")
const Request = require("./QuickRequest")
const { exception } = require('console')


module.exports = app => {
    // console.log(app.config )
    // app.addSingleton('tcp' , createSocketClient ) 
    app.qmt = createSocketClient( app.config.qmt.client , app )
    // app.qmt = RunTime 
}

const isDev = false

class Client {
    
    constructor( config ){
        this.host = config.host 
        this.port = config.port 
        this.requestId = 10 //start with 10.
        this.Request = Request
        this.Response = Response
        this.runtime = RunTime
        this.init() 
        // this.connect()
    }

    init() {
        const app = this

        app.client = new Net.Socket()
        app.client.setEncoding = 'utf-8'

        app.client.on('data' , msg => {
            if( msg.indexOf('health') < 0 || isDev )
                console.log( `Revices : ${msg}`)
            
            try{
                const resp = JSON.parse( msg )
                if( typeof(resp) == 'object' ){
                    //emit event.
                    // Response....
                    Response.invoke( resp )
                }
            }catch(e){
                //continue.
                console.log('OnData error : ' ,e)
            }

        })
        
        app.client.on('error' , e => {
            console.log( 'Print error info :' , e )
            //app.checkState()
        })
        
        app.client.on('close' , () => {
            console.log('connection is closed.')
            app.checkState()
        })

        app.connect()

    }
    
    checkState() {
        const app = this
        console.log(`Check connect' state , destroyed is : ${app.client.destroyed}`)
        if( app.client.destroyed ) {
            console.log('try to reconnect...')
            app.init()
        }
    }

    nextRequestID(){
        return ++this.requestId 
    }

    connect(){
        const app = this
        app.client.connect( this.port , this.host , () => {
            console.log('Connected')

            //login.
            const req = Request.login()

            // const sendMsg = req.toString()
            app.write( req )

            setInterval( function(){
                app.health( )
            } , 10*1000 )
        })
    }

    health( ) {
        const req = Request.health()
        this.write( req )
    }

    write( msg ) {
        if( typeof(msg) === 'object' ){
            const reqId = msg.header.requestId
            if( reqId != -1 && reqId != 0 && !reqId ) {
                msg.setRequestId( this.nextRequestID() )
            }

            if( !msg.header.moduleTag ){
                if( reqId != -1 && reqId != 0 ) {
                    if( RunTime.moduleTag ) {
                        msg.header.moduleTag = RunTime.moduleTag
                    }else{
                        throw new Error('Not logined.')
                    }
                }
            }

            msg = JSON.stringify( msg ) 
        }
        if( msg.indexOf('health') < 0 || isDev )
            console.log('Send:' , msg )
        
        try{
            this.client.write( msg )
        }catch(e){
            this.client.emit("error" , e )
        }
    }

}

function createSocketClient( config , app ) {
    console.log(`Ready to connect by ${config.host} ${config.port}` )
    const cli = new Client( config )
    // cli.init()
    return cli

}

// createSocketClient({
//     host : "127.0.0.1" ,
//     port : 9002 
// })

// const Socket = new Net.Socket()

// const host = '127.0.0.1'
// const port = 9002 

// Socket.setEncoding = 'utf-8'

// Socket.connect( port , host , () => {
//     Socket.write('auth:test')
// })